package pessoas.collection;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
import javax.swing.JOptionPane;
import pessoas.interfaces.IObservado;
import pessoas.interfaces.IObservador;
import pessoas.model.Pessoa;
import pessoas.presenter.apoio.OperacaoArquivo;

public final class Pessoas implements IObservado {

    private TreeSet<Pessoa> pessoas = null;
    private TreeSet<Pessoa> pessoaBusca = null;
    private ArrayList<IObservador> observadores;
    private final File arquivo;
    private static Pessoas instancia;
    private OperacaoArquivo operacao = new OperacaoArquivo();

    public Pessoas() throws FileNotFoundException {
        if (pessoas == null) {
            pessoas = new TreeSet<Pessoa>();
            observadores = new ArrayList<IObservador>();
        }
        arquivo = new File("src/pessoas/data/pessoas.txt");
        carregaPessoas();
    }

    public void carregaPessoas() throws FileNotFoundException {
        Scanner scan = new Scanner(arquivo);
        while (scan.hasNextLine()) {
            String linha = scan.nextLine();
            Scanner scanline = new Scanner(linha);
            scanline.useDelimiter(",");
            while (scanline.hasNext()) {
                String nome = scanline.next();
                String telefone = scanline.next();
                pessoas.add(new Pessoa(nome, telefone));
                
            }
        }
        arquivo.delete();

    }

    public static Pessoas getInstancia() throws FileNotFoundException {
        if (instancia == null) {
            instancia = new Pessoas();
        }
        return instancia;
    }

    public boolean add(Pessoa p) throws IOException {
        boolean add = this.pessoas.add(p);
        if (add) {
            operacao.SalvarTxt(arquivo, p);
        }
        notificar();
        return add;
    }

    public ArrayList<IObservador> getObservadores() {
        return observadores;
    }

    public TreeSet<Pessoa> buscaPessoa(String busca, String tipo) {
        this.pessoaBusca = new TreeSet<Pessoa>();
        Iterator<Pessoa> it = this.pessoas.iterator();
        if (tipo.equals("Nome")) {
            while (it.hasNext()) {
                Pessoa pe = it.next();
                if (pe.getNome().contains(busca)) {
                    this.pessoaBusca.add(pe);
                }
            }
        } else {
            while (it.hasNext()) {
                Pessoa pe = it.next();
                if (pe.getTelefone().contains(busca)) {
                    this.pessoaBusca.add(pe);
                }
            }
        }
        if (pessoaBusca.size() < 1) {

            JOptionPane.showMessageDialog(null, "Nenhum resultado foi obtido!!");
            pessoaBusca = pessoas;
        }
        return pessoaBusca;

    }

    public void excluirPessoa(String telefone) throws IOException {
        Iterator<Pessoa> it = this.pessoas.iterator();
        while (it.hasNext()) {
            Pessoa p = it.next();
            if (p.getTelefone().equals(telefone)) {
                it.remove();
                operacao.limparArquivo(arquivo);
                operacao.adicionaTxt(pessoas, "src/pessoas/data/pessoas.txt");
                
            }
        }
    }

    public void editarPessoa(String telefone) throws IOException {
        excluirPessoa(telefone);
       // notificar();
    }

    public void addAll(Collection ps) {
        this.pessoas.addAll(ps);
    }

    public boolean contains(Pessoa p) {

        return this.pessoas.contains(p);
    }

    public TreeSet<Pessoa> getTreeSet() {
        return pessoas;
    }

    public Iterator<Pessoa> iterator() {
        return this.pessoas.iterator();
    }

    @Override
    public void notificar() {
        for (IObservador i : observadores) {

            i.atualizar();

        }
    }

    @Override
    public void add(IObservador o) {
        observadores.add(o);
    }

    @Override
    public void remove(IObservador o) {
        observadores.remove(o);
    }
}
